package nus.mtech.presistence.oflite;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Object File persistence object. 
 * used to read list of value objects from file 
 *
 * @author  Guo Yu
 */

public class OFReader {
	private Class targetClass;
	private String fileName;
	private BufferedReader br;
	private String delimiter;
	private HashMap<String, Method> methodMap;
	public OFReader(Class targetClass, String fileName) throws IOException{
		this(targetClass, fileName, ",");
	}
	public OFReader(Class targetClass, String fileName, String delimiter) throws IOException{
		this.targetClass = targetClass;
		this.fileName = fileName;
		this.delimiter = delimiter;
		init();
	}
	private void init() throws FileNotFoundException{
		br = new BufferedReader(new FileReader(fileName));
		methodMap = new HashMap<String, Method>();
		Method [] methods = targetClass.getMethods();
		for(Method m:methods){
			if(m.getName().startsWith("set")){
				methodMap.put(m.getName().substring(3), m);
			}
		}
	}
	/**
	 * first line is header. header format: 
	 * value object get and set method name (omit "set" and "get")
	 * refer a.txt for example
	 * @return list of value objects of targetClass type
	 * @throws IOException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public List loadAll() throws IOException, InstantiationException, IllegalAccessException{
		String [] header = readRow();
		List objList = new ArrayList();
		String [] row;
		while((row = readRow())!=null){
			Object obj = targetClass.newInstance();
			for(int i = 0; i < header.length; i++){
				Method m = methodMap.get(header[i]);
				Class type = m.getParameterTypes()[0];
				try{
					if("java.lang.String".equals(type.getName())){
							m.invoke(obj, row[i]);
					}else if("int".equals(type.getName())){
							m.invoke(obj, Integer.valueOf(row[i]).intValue());
					}else if("double".equals(type.getName())){
							m.invoke(obj, Double.valueOf(row[i]).doubleValue());
					}else if("boolean".equals(type.getName())){
							m.invoke(obj, Boolean.valueOf(row[i]).booleanValue());
					}
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			objList.add(obj);
		}
		br.close();
		return objList;
	}
	private String [] readRow() throws IOException{
		String line;
		do{
			line = br.readLine();
		}while(line != null && line.startsWith("--"));
		
		if(line == null)
			return null;
		return line.split(delimiter);
	}
	

}

